﻿using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;

namespace Koala.Pro.Common
{
    public class FileUtil
    {
        public static byte[] StreamToBytes(Stream stream)
        {
            try
            {
                byte[] array = new byte[stream.Length];
                stream.Read(array, 0, Convert.ToInt32(stream.Length));
                stream.Seek(0L, SeekOrigin.Begin);
                return array;
            }
            catch (IOException ex)
            {
                throw ex;
            }
            finally
            {
                stream.Close();
            }
        }

        public static Stream BytesToStream(byte[] bytes)
        {
            return new MemoryStream(bytes);
        }

        public static void BytesToFile(byte[] bytes, string fileName)
        {
            MemoryStream memoryStream = new MemoryStream(bytes);
            FileStream fileStream = new FileStream(fileName, FileMode.OpenOrCreate);
            memoryStream.WriteTo(fileStream);
            memoryStream.Close();
            fileStream.Close();
        }

        public static Image BytesToImage(byte[] bytes)
        {
            MemoryStream obj = new MemoryStream(bytes)
            {
                Position = 0L
            };
            Image result = Image.FromStream(obj);
            obj.Close();
            return result;
        }

        public static byte[] ImageToBytes(Image image)
        {
            byte[] result = null;
            if (image != null)
            {
                lock (image)
                {
                    using MemoryStream memoryStream = new MemoryStream();
                    image.Save(memoryStream, ImageFormat.Png);
                    result = memoryStream.GetBuffer();
                }
            }
            return result;
        }

        public static byte[] ImageToBytes(Image image, ImageFormat imageFormat)
        {
            if (image == null)
            {
                return null;
            }
            byte[] array = null;
            using MemoryStream memoryStream = new MemoryStream();
            using Bitmap bitmap = new Bitmap(image);
            bitmap.Save(memoryStream, imageFormat);
            memoryStream.Position = 0L;
            array = new byte[memoryStream.Length];
            memoryStream.Read(array, 0, Convert.ToInt32(memoryStream.Length));
            memoryStream.Flush();
            return array;
        }

        public static void StreamToFile(Stream stream, string fileName)
        {
            byte[] array = new byte[stream.Length];
            stream.Read(array, 0, array.Length);
            stream.Seek(0L, SeekOrigin.Begin);
            FileStream fileStream = new FileStream(fileName, FileMode.Create);
            BinaryWriter binaryWriter = new BinaryWriter(fileStream);
            binaryWriter.Write(array);
            binaryWriter.Close();
            fileStream.Close();
        }

        public static Stream FileToStream(string fileName)
        {
            FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            byte[] array = new byte[fileStream.Length];
            fileStream.Read(array, 0, array.Length);
            fileStream.Close();
            return new MemoryStream(array);
        }

        public static byte[] FileToBytes(string filePath)
        {
            int fileSize = GetFileSize(filePath);
            byte[] array = new byte[fileSize];
            FileStream fileStream = new FileInfo(filePath).Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            try
            {
                fileStream.Read(array, 0, fileSize);
                return array;
            }
            catch (IOException ex)
            {
                throw ex;
            }
            finally
            {
                fileStream.Close();
            }
        }

        public static string FileToString(string filePath)
        {
            return FileToString(filePath, Encoding.Default);
        }

        public static string FileToString(string filePath, Encoding encoding)
        {
            try
            {
                using StreamReader streamReader = new StreamReader(filePath, encoding);
                return streamReader.ReadToEnd();
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        public static string ReadFileFromEmbedded(string fileWholeName)
        {
            string empty = string.Empty;
            using TextReader textReader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(fileWholeName));
            return textReader.ReadToEnd();
        }

        public static Encoding GetEncoding(string filePath)
        {
            return GetEncoding(filePath, Encoding.Default);
        }

        public static Encoding GetEncoding(string filePath, Encoding defaultEncoding)
        {
            Encoding result = defaultEncoding;
            using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4))
            {
                if (fileStream != null && fileStream.Length >= 2)
                {
                    long position = fileStream.Position;
                    fileStream.Position = 0L;
                    int[] array = new int[4]
                    {
                    fileStream.ReadByte(),
                    fileStream.ReadByte(),
                    fileStream.ReadByte(),
                    fileStream.ReadByte()
                    };
                    fileStream.Position = position;
                    if (array[0] == 254 && array[1] == 255)
                    {
                        result = Encoding.BigEndianUnicode;
                    }
                    if (array[0] == 255 && array[1] == 254)
                    {
                        result = Encoding.Unicode;
                    }
                    if (array[0] == 239 && array[1] == 187 && array[2] == 191)
                    {
                        result = Encoding.UTF8;
                    }
                }
            }
            return result;
        }

        public static int GetFileSize(string filePath)
        {
            return (int)new FileInfo(filePath).Length;
        }

        public static double GetFileSizeKB(string filePath)
        {
            return ConvertHelper.ToDouble(Convert.ToDouble(new FileInfo(filePath).Length) / 1024.0, 1.0);
        }

        public static double GetFileSizeMB(string filePath)
        {
            return ConvertHelper.ToDouble(Convert.ToDouble(new FileInfo(filePath).Length) / 1024.0 / 1024.0, 1.0);
        }

        public static string ToFileSize(long size)
        {
            string result = "";
            long num = 0L;
            num = size;
            if ((double)num < 1024.0)
            {
                result = num.ToString("F2") + " 字节";
            }
            else if ((double)num >= 1024.0 && num < 1048576)
            {
                result = ((double)num / 1024.0).ToString("F2") + " KB";
            }
            else if (num >= 1048576 && num < 1073741824)
            {
                result = ((double)num / 1024.0 / 1024.0).ToString("F2") + " MB";
            }
            else if (num >= 1073741824)
            {
                result = ((double)num / 1024.0 / 1024.0 / 1024.0).ToString("F2") + " GB";
            }
            return result;
        }

        public static void WriteText(string filePath, string content)
        {
            File.WriteAllText(filePath, content, Encoding.Default);
        }

        public static void AppendText(string filePath, string content)
        {
            File.AppendAllText(filePath, content, Encoding.Default);
        }

        public static void Copy(string sourceFilePath, string destFilePath)
        {
            File.Copy(sourceFilePath, destFilePath, overwrite: true);
        }

        public static void Move(string sourceFilePath, string descDirectoryPath)
        {
            string fileName = GetFileName(sourceFilePath);
            if (Directory.Exists(descDirectoryPath))
            {
                if (IsExistFile(descDirectoryPath + "\\" + fileName))
                {
                    DeleteFile(descDirectoryPath + "\\" + fileName);
                }
                File.Move(sourceFilePath, descDirectoryPath + "\\" + fileName);
            }
        }

        public static bool IsExistFile(string filePath)
        {
            return File.Exists(filePath);
        }

        public static bool IsExistDirectory(string directoryPath)
        {
            return Directory.Exists(directoryPath);
        }

        public static void CreateFile(string filePath)
        {
            try
            {
                if (!IsExistFile(filePath))
                {
                    File.Create(filePath);
                }
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        public static void CreateFile(string filePath, byte[] buffer)
        {
            try
            {
                if (!IsExistFile(filePath))
                {
                    using (FileStream fileStream = File.Create(filePath))
                    {
                        fileStream.Write(buffer, 0, buffer.Length);
                        return;
                    }
                }
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        public static int GetLineCount(string filePath)
        {
            return File.ReadAllLines(filePath).Length;
        }

        public static string GetFileName(string filePath)
        {
            return new FileInfo(filePath).Name;
        }

        public static string GetFileNameNoExtension(string filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            return fileInfo.Name.Substring(0, fileInfo.Name.LastIndexOf('.'));
        }

        public static string GetExtension(string filePath)
        {
            return new FileInfo(filePath).Extension;
        }

        public static void ClearFile(string filePath)
        {
            File.Delete(filePath);
            CreateFile(filePath);
        }

        public static void DeleteFile(string filePath)
        {
            if (IsExistFile(filePath))
            {
                File.Delete(filePath);
            }
        }

        public static bool FileIsExist(string path)
        {
            return File.Exists(path);
        }

        public static bool FileIsReadOnly(string fullpath)
        {
            if ((new FileInfo(fullpath).Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
            {
                return true;
            }
            return false;
        }

        public static void SetFileReadonly(string fullpath, bool flag)
        {
            FileInfo fileInfo = new FileInfo(fullpath);
            if (flag)
            {
                fileInfo.Attributes |= FileAttributes.ReadOnly;
            }
            else
            {
                fileInfo.Attributes &= ~FileAttributes.ReadOnly;
            }
        }

        public static string GetFileName(string fullpath, bool removeExt)
        {
            string text = new FileInfo(fullpath).Name;
            if (removeExt)
            {
                text = text.Remove(text.LastIndexOf('.'));
            }
            return text;
        }

        public static DateTime GetFileCreateTime(string fullpath)
        {
            return new FileInfo(fullpath).CreationTime;
        }

        public static DateTime GetLastWriteTime(string fullpath)
        {
            return new FileInfo(fullpath).LastWriteTime;
        }

        public static string CreateTempZeroByteFile()
        {
            return Path.GetTempFileName();
        }

        public static string GetRandomFileName()
        {
            return Path.GetRandomFileName();
        }

        public static bool CompareFilesHash(string fileName1, string fileName2)
        {
            using HashAlgorithm hashAlgorithm = HashAlgorithm.Create();
            using FileStream inputStream = new FileStream(fileName1, FileMode.Open);
            using FileStream inputStream2 = new FileStream(fileName2, FileMode.Open);
            byte[] array = hashAlgorithm.ComputeHash(inputStream);
            byte[] array2 = hashAlgorithm.ComputeHash(inputStream2);
            return BitConverter.ToString(array) == BitConverter.ToString(array2);
        }

        public static object LoadObjectFromXml(string path, Type type)
        {
            object obj = null;
            using StreamReader streamReader = new StreamReader(path);
            return XmlConvertor.XmlToObject(streamReader.ReadToEnd(), type);
        }

        public static void SaveObjectToXml(string path, object obj)
        {
            string value = XmlConvertor.ObjectToXml(obj, toBeIndented: true);
            using StreamWriter streamWriter = new StreamWriter(path);
            streamWriter.Write(value);
        }

        public static void OpenFileInProcess(string fileName, byte[] bytes)
        {
            string tempFilePath = Path.Combine(DirectoryUtil.GetTempPath(), fileName);
            if (File.Exists(tempFilePath))
            {
                File.Delete(tempFilePath);
            }
            BytesToFile(bytes, tempFilePath);
            GetExtension(tempFilePath);
            GetFileName(tempFilePath);
            new Thread((ThreadStart)delegate
            {
                Process process = Process.Start(tempFilePath);
                process.WaitForExit();
                if (File.Exists(tempFilePath))
                {
                    File.Delete(tempFilePath);
                }
                process.Close();
            }).Start();
        }
    }
}
